#pragma once
#include<iostream>
#include<string>
#include"nocopy.hpp"
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include"Log.hpp"
#include<cerrno>
#include <string.h>
#include"InetAddr.hpp"
#include<functional>
enum{
    Usage_Err = 1,
    Socket_Err,
    Bind_Err
};
const static uint16_t defaultport=8888;
const static int defaultfd=-1;
const static int defaultsize=1024;


using func_t=std::function<std::string(std::string)>;
class UdpServer:public nocopy    //设置为不可被拷贝
{
    public:
    UdpServer(func_t OnMessage,uint16_t port=defaultport)
    :_port(port),_sockfd(defaultfd),_OnMessage(OnMessage)
    {

    }
    void Init()
    {
        //创建socket
        _sockfd=socket(AF_INET,SOCK_DGRAM,0);
        if(_sockfd<0)
        {
            lg.LogMessage(Fatal,"socket erro,%d:%s\n",errno,strerror(errno));
            exit(Socket_Err);
        }
        lg.LogMessage(Info,"socket sucess,socket: %d\n",_sockfd);

hhjv
        //2、绑定
        struct sockaddr_in local;
        bzero(&local,sizeof(local));
        local.sin_family=AF_INET;
        local.sin_port=htons(_port);
        local.sin_addr.s_addr=INADDR_ANY;  //0,可以指定为任意IP


        //设置进内核
        int n=bind(_sockfd,(struct sockaddr*)&local,sizeof(local));
        if(n!=0)
        {
            lg.LogMessage(Fatal, "bind errr, %d : %s\n", errno, strerror(errno));
            exit(Bind_Err);
        }

    }

    void Start()
    {
        char buffer[defaultsize];
        while(true)
        {
            struct sockaddr_in peer;
            socklen_t len=sizeof(peer);
            ssize_t n=recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
            if(n>0)
            {
                InetAddr addr(peer);
                buffer[n]=0;
                //处理指令后的回应
                std::string response=_OnMessage(buffer);
                std::cout<<"["<<addr.PrintDebug()<<"]#"<<buffer<<std::endl;
                std::cout<<response<<" "<<response.size()<<std::endl;
                sendto(_sockfd,response.c_str(),response.size(),0,(struct sockaddr*)&peer,len);
            }
        }

    }
    ~UdpServer()
    {

    }


private:
    uint16_t _port;
    int  _sockfd;

    func_t _OnMessage;  //回调

};